package com.clerkq.SoundPlayer
{
	import com.clerkq.FlvPlayer.ui.ProgressIndicator;
	import com.clerkq.FlvPlayer.ui.VolumeBar;
	import com.content.model.LoadedAssets.SkinProxy;
	import com.content.view.Component.Button.HighLightButton;
	import com.content.view.Component.Button.HighLightToggleButton;
	import com.library.core.IDisposable;
	import com.library.core.UIObject;
	import com.library.utils.NumberUtil;
	import com.library.utils.StringUtil;
	import com.library.utils.Tick.Tick;
	import com.library.utils.Tick.TickEvent;
	
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	import flash.net.URLRequest;
	
	public class SoundPlayer extends UIObject implements IDisposable
	{
		private var _sound:Sound;
		private var _sChannel:SoundChannel;
		private var _url:String;
		private var _duration:Number;// = 0
		private var _lastPosition:Number = 0;
		private var _volumeBeforeMute:Number;
		
		private var _playBtn:HighLightToggleButton;
		private var _muteBtn:HighLightButton;
		private var _progressBar:ProgressIndicator;
		private var _volumeBar:VolumeBar;
		private var _frame:Sprite;
		
		public function SoundPlayer()
		{
			super();
			_duration = 0;
			
			_sound = new Sound();
			_sChannel = new SoundChannel();
			
			_frame = new SkinProxy.SoundPlayer_PlayerFrame() as Sprite;
			addChild(_frame);
			_frame.x = 1.5;
			_frame.y = 2;
			
			// Play Button (Play/Pause in one button)
			var playNormal:MovieClip = new SkinProxy.VideoPlayer_PlayButton() as MovieClip;
			var playLight:MovieClip = new SkinProxy.VideoPlayer_PlayButtonLight() as MovieClip;
			_playBtn = new HighLightToggleButton(playNormal, playLight);
			addChild(_playBtn);			
			_playBtn.x = 8;
			_playBtn.y = 0;
			
			// Mute Button
			var muteNormal:Sprite = new SkinProxy.VideoPlayer_Mute() as Sprite;
			var muteLight:Sprite = new SkinProxy.VideoPlayer_MuteLight() as Sprite;
			_muteBtn = new HighLightButton(muteNormal, muteLight);
			addChild(_muteBtn);			
			_muteBtn.x = 413;
			_muteBtn.y = 14;
			
			_progressBar = new ProgressIndicator();
			addChild(_progressBar);			
			_progressBar.x = 65;
			_progressBar.y = 10;
			
			_volumeBar = new VolumeBar();
			_volumeBar.percent = 0.5;
			addChild(_volumeBar);			
			_volumeBar.x = 432;
			_volumeBar.y = 18;
			
			AddListener();
		}
		
		private function AddListener():void{
			_playBtn.addEventListener(MouseEvent.CLICK, onControlBtnClick);
			_muteBtn.addEventListener(MouseEvent.CLICK, onControlBtnClick);
			_muteBtn.addEventListener(MouseEvent.CLICK, onSoundSwitch);
			_volumeBar.addEventListener(VolumeBar.SOUND_CHANGE, onSoundChange);
			_progressBar.addEventListener(ProgressIndicator.ON_PRESS_PLAYHEAD, onProgressBarEvent);
			_progressBar.addEventListener(ProgressIndicator.ON_RELEASE_PLAYHEAD, onProgressBarEvent);
		}
		
		private function RemoveListener():void{
			_playBtn.removeEventListener(MouseEvent.CLICK, onControlBtnClick);
			_muteBtn.removeEventListener(MouseEvent.CLICK, onControlBtnClick);
			_muteBtn.removeEventListener(MouseEvent.CLICK, onSoundSwitch);
			_volumeBar.removeEventListener(VolumeBar.SOUND_CHANGE, onSoundChange);
			_progressBar.removeEventListener(ProgressIndicator.ON_PRESS_PLAYHEAD, onProgressBarEvent);
			_progressBar.removeEventListener(ProgressIndicator.ON_RELEASE_PLAYHEAD, onProgressBarEvent);
		}
		
		// EVENT /////////////////////////////////////////////////////
		private function onProgressBarEvent(evt:Event):void{
			switch(evt.type)
			{
				case ProgressIndicator.ON_PRESS_PLAYHEAD:
					PauseForSeek();
					break;
				case ProgressIndicator.ON_RELEASE_PLAYHEAD:
					ResumeAfterSeek(_progressBar.dragPercent);
					break;
			}
		}
		private function onControlBtnClick(evt:MouseEvent):void{
			switch(evt.target)
			{
				case _playBtn:
					if(_playBtn.isToggle){
						// 如果已经播完，则不是 resume，而是 replay 了
						var playedSec:int = int(_sChannel.position) / 1000;
						var totalSec:int = int(_sound.length) / 1000;
						if(playedSec >= totalSec){
							Play(_url);
						}else{
							Resume();
						}
						
					}else{
						Pause();
					}
					break;
				case _muteBtn:
					break;
			}
		}
		private function onSoundSwitch(evt:MouseEvent):void
		{
			if(_volumeBar.percent != 0){
				// Mute
				_volumeBeforeMute = _volumeBar.percent;
				_volumeBar.percent = 0;
				_sChannel.soundTransform = new SoundTransform(_volumeBar.percent, 0);
			}else{
				// Unmute (Back to previous value)
				_volumeBar.percent = _volumeBeforeMute;
				_sChannel.soundTransform = new SoundTransform(_volumeBar.percent, 0);
			}
		}
		
		private function onSoundChange(evt:Event):void
		{
			_sChannel.soundTransform = new SoundTransform(_volumeBar.percent, 0);
		}
		
		private function onUpdate(evt:TickEvent):void{
			try {
				_progressBar.playPercent = _sChannel.position/_sound.length;
				
				var playedSec:int = int(_sChannel.position) / 1000;
				var playedStr:String=StringUtil.FormatMinute(playedSec);
				var totalSec:int = int(_sound.length) / 1000;
				var totalStr:String=StringUtil.FormatMinute(totalSec);
				_progressBar.displayText = playedStr+" / "+totalStr;
				if(playedSec >= totalSec) Pause();
				
			} catch(evt:Error) {
			};
		}
			
		
		public function Play(soundUrl:String=""):void{
			_sChannel.stop();
			_sound = new Sound();
			_playBtn.isToggle = true;
			_progressBar.reset();
			_url = soundUrl; 
			_sound.load(new URLRequest(soundUrl));
			_sChannel = _sound.play();
			Tick.getInstance().addEventListener(TickEvent.TICK, onUpdate);
		}
		
		public function Pause():void{
			Tick.getInstance().removeEventListener(TickEvent.TICK, onUpdate);
			_lastPosition = _sChannel.position;
			_sChannel.stop();
			_playBtn.isToggle = false;
		}
		
		public function Resume():void{
			Tick.getInstance().addEventListener(TickEvent.TICK, onUpdate);
			_sChannel = _sound.play(_lastPosition);
			_playBtn.isToggle = true;
		}
		
		public function ResumeAfterSeek(percent:Number):void{
			Tick.getInstance().addEventListener(TickEvent.TICK, onUpdate);
			_sChannel = _sound.play(_sound.length * percent);
			_playBtn.isToggle = true;
		}
		
		public function PauseForSeek():void{
			Pause();
		}
		
		public function Dispose():void
		{
			RemoveListener();
			
			_playBtn.Dispose();
			_muteBtn.Dispose();
			_progressBar.Dispose();
			_volumeBar.Dispose();
			Tick.getInstance().removeEventListener(TickEvent.TICK, onUpdate);
			
			// 3. Remove all
			removeAllChilds();
		}
	}
}